package org.tio.core.maintain;

import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.cache.IpStatRemovalListener;
import org.tio.core.stat.IpStat;
import org.tio.json.Json;
import org.tio.utils.cache.guava.GuavaCache;
import org.tio.utils.time.Time;

/**
 *
 * @author tanyaowu
 * 2017年4月15日 下午12:13:19
 */
public class Ips {
	private static Logger log = LoggerFactory.getLogger(Ips.class);

	private String id;

	private final static String CACHE_NAME = "TIO_IP_STAT";
	private final static Long timeToLiveSeconds = null;
	private final static Long timeToIdleSeconds = Time.DAY_1;

	private String cacheName = null;
	private GuavaCache cache = null;

	@SuppressWarnings("unchecked")
	public Ips(String id) {
		this.id = id;
		this.cacheName = CACHE_NAME + this.id;
		this.cache = GuavaCache.register(this.cacheName, timeToLiveSeconds, timeToIdleSeconds, new IpStatRemovalListener());
	}

	/**
	 * 根据ip获取IpStat，如果缓存中不存在，则创建
	 * @param ip
	 * @return
	 * @author: tanyaowu
	 */
	public IpStat get(String ip) {
		return get(ip, true);
	}

	/**
	 * 根据ip获取IpStat，如果缓存中不存在，则根据forceCreate的值决定是否创建
	 * @param ip
	 * @param forceCreate
	 * @return
	 * @author: tanyaowu
	 */
	public IpStat get(String ip, boolean forceCreate) {
		if (StringUtils.isBlank(ip)) {
			return null;
		}
		IpStat ipStat = (IpStat) cache.get(ip);
		if (ipStat == null && forceCreate) {
			synchronized (this) {
				ipStat = (IpStat) cache.get(ip);
				if (ipStat == null) {
					ipStat = new IpStat(ip);
					cache.put(ip, ipStat);
				}
			}
		}
		return ipStat;
	}

	/**
	 * 打印
	 * 
	 * @author: tanyaowu
	 */
	public void print() {
		synchronized (this) {
			ConcurrentMap<String, Serializable> map = cache.asMap();
			log.info(Json.toFormatedJson(map));
		}
	}

	/**
	 * 
	 * @return
	 * @author: tanyaowu
	 */
	public ConcurrentMap<String, Serializable> map() {
		ConcurrentMap<String, Serializable> map = cache.asMap();
		return map;
	}

	/**
	 * 
	 * @return
	 * @author: tanyaowu
	 */
	public Collection<Serializable> values() {
		Collection<Serializable> set = cache.asMap().values();
		return set;
	}

	/**
	 * 
	 * 
	 * @author: tanyaowu
	 */
	public void clear() {
		cache.clear();
	}

	/**
	 * 
	 * @return
	 * @author: tanyaowu
	 */
	public long size() {
		return cache.size();
	}

}
